import { type Component, createApp, h, nextTick, ref } from 'vue'
import BaseDialog from '~/components/BaseDialog.vue'

interface ModalProps {
  title?: string
  show?: boolean
  icon?: string
  iconPosition?: 'left' | 'right'
  showClose?: boolean
  size?: Array<string | number>
  showLoading?: boolean
  showHeader?: boolean
  bgColor?: string
  noPadding?: boolean
  zIndex?: number
  titleCom?: VNode | Component
  closeCb?: () => void
}

export function useDialog(component: Component, props: any, modalProps: ModalProps = {}) {
  const nuxtApp = useNuxtApp()
  const i18n = nuxtApp.$i18n
  const show = ref(false)
  let app: ReturnType<typeof createApp> | null = null
  let container: HTMLDivElement | null = null
  let isMounted = false

  const close = (destroy = false) => {
    show.value = false
    modalProps?.closeCb?.()

    if (destroy && isMounted) {
      nextTick(() => {
        app?.unmount()
        if (container) {
          document.body.removeChild(container)
        }
        isMounted = false
        app = null
        container = null
      })
    }
  }

  const open = (params: any | ModalProps = {}) => {
    if (!isMounted) {
      const dialog = {
        setup() {
          provide('i18n', i18n.t)

          const slots: Record<string, Component> = {
            default: () => h(component, { ...props, ...params, isOpen: show.value, close: (destroy = false) => close(destroy) }),
          }
          if (modalProps?.titleCom) {
            slots.title = modalProps?.titleCom
          }

          return () =>
            h(
              BaseDialog,
              { ...modalProps, show: show.value, onClose: () => close(false) },
              slots,
            )
        },
      }
      app = createApp(dialog)

      container = document.createElement('div')
      document.body.appendChild(container)
      app.mount(container)
      isMounted = true
    }
    show.value = true
  }

  const unmount = () => close(true)

  return {
    open,
    close,
    unmount,
  }
}
